<template>
  <el-dialog
    v-model="visible"
    title="发送图片"
    width="500px"
    :before-close="handleClose"
    class="image-upload-dialog"
  >
    <div class="upload-container">
      <el-upload
        ref="fileUploadRef"
        drag
        multiple
        :show-file-list="false"
        action=""
        :limit="5"
        accept=".zip, .doc, .docx, .pdf, .txt, .xls, .xlsx"
        :before-upload="handleFileBeforeUpload"
        :on-exceed="handleExceed"
      >
        <div class="upload-area">
          <el-icon class="upload-icon"><Folder /></el-icon>
          <div class="upload-text">点击或拖拽文件到此处上传</div>
          <div class="upload-hint">支持文档、图片、视频、音频、压缩包等格式，单个文件不超过 50MB</div>
        </div>
      </el-upload>
    </div>

    <!-- 上传进度 -->
    
    <div v-if="isFileUploading" class="flex items-center space-x-2">
      <el-progress :percentage="100" :show-text="false" />
      <span class="text-sm text-gray-600">上传中...</span>
    </div>

    <!-- 已上传文件预览 -->
    <div v-if="uploadedFiles.length > 0" class="uploaded-files-section">
        <div class="section-title">
        已选择的文件 ({{ uploadedFiles.length }})
        </div>
        <div class="images-grid">
            <div
                v-for="(file, index) in uploadedFiles"
                :key="index"
                class="file-item"
            >
              <div class="flex">
                <div class="mr10">
                  {{ getFileIcon(file.name) }}
                </div>
                <div class="min-w-0 flex-1">
                  <div class="truncate text-sm text-gray-900 font-medium">
                    {{ file.name }}
                  </div>
                  <div class="text-xs text-gray-500">
                    {{ formatFileSize(file.size) }}
                  </div>
                </div>
              </div>

              <div class="file-overlay">
                <el-button
                    type="danger"
                    size="small"
                    circle
                    @click="removeUploadedImage(index)"
                    class="delete-btn"
                >
                    <el-icon><Delete /></el-icon>
                </el-button>
                </div>
            </div>
        </div>
    </div>


    <template #footer>
        <div class="footer-wrap">
            <div class="text-sm text-gray-500">
            {{ uploadedFiles.length }}/5 个文件
            </div>
            <div class="space-x-2">
            <el-button @click="visible = false">
                取消
            </el-button>
            <el-button
                type="primary"
                :disabled="uploadedFiles.length === 0 || isFileUploading"
                @click="sendFileMessages"
            >
                发送 {{ uploadedFiles.length > 0 ? `(${uploadedFiles.length})` : '' }}
            </el-button>
            </div>
        </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, defineExpose, nextTick, defineEmits} from 'vue'
import { ElMessage } from 'element-plus'
import { Folder, Delete } from '@element-plus/icons-vue'
import type { UploadFile, UploadFiles } from 'element-plus'
import { useIMStore } from '/@/stores/im'
import { truncate } from 'node:fs/promises'
import COS from 'cos-js-sdk-v5'
import dayjs from 'dayjs'
import api from "/@/api/common";

// 定义 emits
const emit = defineEmits(['send-images'])
const cosObj = new COS({
  Protocol: 'https:', // 使用 https 协议
  async getAuthorization(options: any, callback) {
    const { data } = await api.getCredential()
    console.log(options)
    callback({
      TmpSecretId: data.tmpSecretId,
      TmpSecretKey: data.tmpSecretKey,
      SecurityToken: data.sessionToken,
      // 建议返回服务器时间作为签名的开始时间，避免客户端本地时间偏差过大导致签名错误
      StartTime: data.startTime, // 时间戳，单位秒，如：1580000000
      ExpiredTime: data.expiredTime, // 时间戳，单位秒，如：1580000000
      ScopeLimit: true, // 细粒度控制权限需要设为 true，会限制密钥只在相同请求时重复使用
    })
  },
})

const imStore = useIMStore()
// 响应式数据
const isFileUploading = ref(false)
const uploadedFiles = ref<any[]>([])
const visible = ref(false)
const fileList = ref<UploadFile[]>([])
const uploadRef = ref()

const fileUploadingCount = ref(0)

const getFileIcon = (fileName: string) => {
  if (!fileName) return '📄'
  const ext = fileName.split('.').pop()?.toLowerCase()
  const icons = {
    // 文档
    'pdf': '📕', 'doc': '📘', 'docx': '📘', 'txt': '📝',
    // 表格
    'xls': '📊', 'xlsx': '📊', 'csv': '📊',
    // 演示文稿
    'ppt': '📋', 'pptx': '📋',
    // 图片
    'jpg': '🖼️', 'jpeg': '🖼️', 'png': '🖼️', 'gif': '🖼️',
    // 压缩文件
    'zip': '🗜️', 'rar': '🗜️', '7z': '🗜️',
    // 音视频
    'mp3': '🎵', 'wav': '🎵', 'mp4': '🎬', 'avi': '🎬',
    // 代码
    'js': '💻', 'ts': '💻', 'vue': '💻', 'py': '🐍'
  }
  return icons[ext || ''] || '📄'
}

// 格式化文件大小
function formatFileSize(bytes: number): string {
  if (bytes === 0) { return '0 Bytes' }
  const k = 1024
  const sizes = ['Bytes', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return `${Number.parseFloat((bytes / k ** i).toFixed(2))} ${sizes[i]}`
}

/**
 * 上传超出10张图片时的处理
 */
const handleExceed = () => {
    return ElMessage.error('已达到最大上传数量(10张)，请先删除一些图片')
}


// 移除已上传的图片
function removeUploadedImage(index: number) {
  uploadedFiles.value.splice(index, 1)
}

// 发送文件消息
async function sendFileMessages() {
  if (uploadedFiles.value.length === 0) {
    ElMessage.warning('请先上传文件')
    return
  }

  if (!imStore.currentConversation) {
    ElMessage.warning('请先选择聊天对象')
    return
  }

  const to = imStore.currentConversation?.userProfile?.userID
  if (!to) {
    ElMessage.warning('无法获取聊天对象信息')
    return
  }

  let successCount = 0
  let failCount = 0

  // 发送每个文件
  for (const [index, file] of uploadedFiles.value.entries()) {
    try {
      const result = await imStore.sendFileCustomMessage(file.url, file.name, file.size, to, 'C2C')
      if (result && result.code === 0) {
        successCount++
      }
      else {
        failCount++
        console.error(`文件 ${index + 1} 发送失败:`, result)
      }
    }
    catch (error) {
      failCount++
      console.error(`文件 ${index + 1} 发送异常:`, error)
    }
  }

  if (successCount > 0) {
    ElMessage.success(`成功发送 ${successCount} 个文件`)
  }
  if (failCount > 0) {
    ElMessage.error(`发送失败 ${failCount} 个文件`)
  }

  visible.value = false
  uploadedFiles.value = []
  fileUploadingCount.value = 0
}

// 处理文件上传前的验证
async function handleFileBeforeUpload(file: File) {
  // 检查文件数量限制
  const currentCount = uploadedFiles.value.length + fileUploadingCount.value

  if (currentCount >= 5) {
    ElMessage.error('最多只能上传5个文件!')
    return false
  }

  // 检查文件类型
  const allowedTypes = [
    '.zip',
    '.rar',
    '.7z',
    '.doc',
    '.docx',
    '.pdf',
    '.txt',
    '.xls',
    '.xlsx',
    '.ppt',
    '.pptx',
    '.jpg',
    '.jpeg',
    '.png',
    '.gif',
    '.bmp',
    '.webp',
    '.mp4',
    '.avi',
    '.mov',
    '.wmv',
    '.flv',
    '.mp3',
    '.wav',
    '.flac',
    '.aac',
  ]

  const fileExtension = `.${file.name.split('.').pop()?.toLowerCase()}`
  if (!allowedTypes.includes(fileExtension)) {
    ElMessage.error(`不支持的文件类型: ${fileExtension}`)
    return false
  }

  // 检查文件大小（50MB限制）
  const isLt50M = file.size / 1024 / 1024 < 50
  if (!isLt50M) {
    ElMessage.error('文件大小不能超过 50MB!')
    return false
  }

  // 立即增加上传计数
  fileUploadingCount.value++

  // 先添加占位项
  const placeholderItem = {
    uid: file.name + Date.now(),
    url: '',
    name: file.name,
    size: file.size,
    type: file.type,
    file,
    loading: true,
  }
  uploadedFiles.value.push(placeholderItem)

  isFileUploading.value = true
  try {
    const fileName = `/uploads/files/${dayjs().format('YYYYMMDD')}/${new Date().getTime()}_${file.name}`
    const result = await cosObj.uploadFile({
      Bucket: 'yj-mail-1307961934',
      Region: 'ap-shanghai',
      Key: fileName,
      Body: file,
    })

    if (result.statusCode === 200) {
      const fileUrl = `https://${result.Location}`
      // 更新占位项
      const index = uploadedFiles.value.findIndex((item:any) => item.uid === placeholderItem.uid)
      if (index !== -1) {
        uploadedFiles.value[index] = {
          url: fileUrl,
          name: file.name,
          size: file.size,
          type: file.type,
          file,
          uid: placeholderItem.uid,
        }
      }
      ElMessage.success('文件上传成功')
    }
    else {
      // 上传失败，移除占位项
      const index = uploadedFiles.value.findIndex((item:any) => item.uid === placeholderItem.uid)
      if (index !== -1) {
        uploadedFiles.value.splice(index, 1)
      }
      ElMessage.error('文件上传失败')
    }
  }
  catch (error) {
    console.error('文件上传失败:', error)
    ElMessage.error('文件上传失败')
    // 上传失败，移除占位项
    const index = uploadedFiles.value.findIndex((item:any) => item.uid === placeholderItem.uid)
    if (index !== -1) {
      uploadedFiles.value.splice(index, 1)
    }
  }
  finally {
    isFileUploading.value = false
    fileUploadingCount.value--
  }

  return false // 阻止 el-upload 的默认上传行为
}

// 关闭弹窗
const handleClose = () => {
  visible.value = false
}

const open = (list:any[]) => {
  if(list && list.length > 0) {
    uploadedFiles.value = list
  }else {
    uploadedFiles.value = []
  }
  visible.value = true
  fileUploadingCount.value = 0
}

defineExpose({ open })
</script>

<style scoped lang="scss">
.footer-wrap {
    padding: 16px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
/* 图片网格布局样式 */
.uploaded-files-section {
    margin-top: 16px;
    margin-bottom: 16px;
}

.section-title {
    font-size: 14px;
    color: #606266;
    font-weight: 500;
    margin-bottom: 12px;
}

.images-grid {
    display: grid;
    grid-template-columns: repeat(1, 1fr);
    gap: 12px;
}

.file-item {
    position: relative;
    width: 100%;
    // height: 100px;
    border: 1px solid #e4e7ed;
    border-radius: 8px;
    overflow: hidden;
    background-color: #f5f7fa;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px;
}

.image-preview {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.file-overlay {
    // position: absolute;
    // top: 0;
    // left: 0;
    // right: 0;
    // bottom: 0;
    // background-color: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 1;
    transition: opacity 0.2s ease;
    border-radius: 8px;
}

// .file-item:hover .file-overlay {
//     opacity: 1;
// }

.delete-btn {
    background-color: #f56c6c !important;
    border-color: #f56c6c !important;
    color: white !important;
}

.delete-btn:hover {
    background-color: #f78989 !important;
    border-color: #f78989 !important;
}
</style>
